package com.example.demo.utils.Date;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期类
 * @author 微凉
 *
 */
public class DateUtil {
	
	private static final String yyyy_MM_dd_HH_mm_ss="yyyy-MM-dd HH:mm:ss";
	private static final String yyyy_MM_dd = "yyyy-MM-dd";
	private static final String yyyy_MM = "yyyy-MM";
	private static final String year = "yyyy";
	private static final String month = "MM";
	private static final String day = "dd";
	/**
	 * 获取时间戳
	 * @return
	 */
	public static long getMessageCreateTime() {
		Date dateTime = new Date();
		long time=dateTime.getTime();
		return time;
	}
	
	/**
	 * 获取当前时间（年-月-日 时-分-秒）
	 * @return
	 */
	public static String getNowTime() {
	    return getFormatTime(yyyy_MM_dd_HH_mm_ss);
	}
	
	/**
	 * 获取当前日期
	 * @return
	 */
	public static String getDate() {
		return getFormatTime(yyyy_MM_dd);
	}
	/**
	 * 获取想要格式的日期
	 * @param format 日期格式
	 * @return
	 */
	public static String getFormatTime(String format) {
		Date date=new Date();
	    SimpleDateFormat sFormat=new SimpleDateFormat(format);
	    String time = sFormat.format(date);
	    return time;
	}
	
	/**
	 * 获取年份
	 * @return
	 */
	public static String getYear() {
		return getFormatTime(year);
	}

	/**
	 * 获取月份
	 * @return
	 */
	public static String getMonth() {
		return getFormatTime(month);
	}

	/**
	 * 获取日
	 * @return
	 */
	public static String getDay() {
		return getFormatTime(day);
	}

	/**
	 * 格式化日期（date转string）
	 * @param date
	 * @param formatStr 日期格式
	 * @return
	 */
	public static String parseDate(Date date, String formatStr) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
		if (null == date) {
			return null;
		}
		return dateFormat.format(date);
	}

	/**
	 * 把long型日期转String
	 * @param date long型日期；
	 * @param format 日期格式；
	 * @return string
	 */
	public static String longToString(long date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date dt2 = new Date(date);
		String sDateTime = sdf.format(dt2); // 得到精确到秒的表示
		return sDateTime;
	}
	
	/**
	 * date转String
	 * @param date
	 * @param formatStr
	 * @return
	 */
	public static String dateToString(Date date, String formatStr) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
		if (date == null) {
			return null;
		}
		return dateFormat.format(date);
	}
	
	/**
     * string转时间戳
     * @param time
     * @return long
     */
    public static long stringToStamp(String time) {
    	long timestamp = 0;
        try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = simpleDateFormat.parse(time);
			timestamp = date.getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}
        return timestamp;
    }
    
    /**
	 * 字符串转date
	 * @param strDateTime 字符串日期
	 * @param dateTimeFormat 日期格式
	 * @return Date
	 */
	public static Date stringToDate(String strDateTime, String dateTimeFormat) {
		if ((strDateTime == null) || (strDateTime.length() == 0) || (dateTimeFormat == null) || (dateTimeFormat.length() == 0)) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(dateTimeFormat);
		Date date = dateFormat.parse(strDateTime, new ParsePosition(0));
		if (date == null) {
			return null;
		}
		return date;
	}
	
	/**
     * date转时间戳
     * @param date
     * @return long
     */
    public static long dateToStamp(Date date) {
		return date.getTime();
	}
    
    /**
	 * 比较两个时间的大小（返回true：a<b，false：a>b）
	 * @param time1 时间字符串
	 * @param time2 时间字符串
	 * @return yyyy_MM_dd
	 */
	public static boolean compareDate(String a , String b) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM_dd);
			// 将字符串形式的时间转化为Date类型的时间
			Date time1 = sdf.parse(a);
			Date time2 = sdf.parse(b);
			// Date类的一个方法，如果a早于b返回true，否则返回false
			if (time1.before(time2)) {
				return true;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 比较两个时间的大小（返回true：a<b，false：a>b）
	 * @param time1 时间字符串
	 * @param time2 时间字符串
	 * @return yyyy_MM_dd_HH_mm_ss
	 */
	public static boolean compareDateTime(String a , String b) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss);
			// 将字符串形式的时间转化为Date类型的时间
			Date time1 = sdf.parse(a);
			Date time2 = sdf.parse(b);
			// Date类的一个方法，如果a早于b返回true，否则返回false
			if (time1.before(time2)) {
				return true;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 计算两个时间相差
	 * @param startTime
	 * @param endTime
	 * @param format
	 * @param str 返回标识，d返回相差天、h返回相差小时、m返回相差分钟、s返回相差秒
	 * @return
	 */
	public static Long dateDiff(String startTime, String endTime, String format, String str) {
		// 按照传入的格式生成一个simpledateformate对象
		SimpleDateFormat sd = new SimpleDateFormat(format);
		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
		long nh = 1000 * 60 * 60;// 一小时的毫秒数
		long nm = 1000 * 60;// 一分钟的毫秒数
		long ns = 1000;// 一秒钟的毫秒数
		long diff;
		long day = 0;
		long hour = 0;
		long min = 0;
		long sec = 0;
		// 获得两个时间的毫秒时间差异
		try {
			diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
			day = diff / nd;// 计算差多少天
			hour = diff % nd / nh + day * 24;// 计算差多少小时
			min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
			sec = diff % nd % nh % nm / ns;// 计算差多少秒
		} catch (ParseException e) {
			e.printStackTrace();
		}
		if (str.equalsIgnoreCase("d"))
			return day;
		else if (str.equalsIgnoreCase("h"))
			return (day*24)+hour;
		else if (str.equalsIgnoreCase("m"))
			return (day*24*60)+(hour*60)+min;
		else if (str.equalsIgnoreCase("s"))
			return (day*24*3600)+(hour*3600)+(min*60)+sec;
		else
			return 0L;
	}

	/**
	 * 获取本月1号
	 * @return
	 */
	public static String getCurrentMonthHead() {
		Calendar c = Calendar.getInstance();
		c.set(GregorianCalendar.DAY_OF_MONTH, 1);
		Date MonthHead = c.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM_dd);
		String preMonthHead = sdf.format(MonthHead);
		return preMonthHead;
	}
	
	/**
	 * 获取今年1号
	 */
	public static String getCurrentYearHead() {
		int months = 0;
		Calendar c = Calendar.getInstance();
		c.set(Calendar.MONTH, c.get(Calendar.MONTH) + months);
		c.set(Calendar.DAY_OF_YEAR, 1);
		Date MonthHead = c.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM_dd);
		String preMonthHead = sdf.format(MonthHead);
		return preMonthHead;
	}
	
	/**
     * 获取当前时间前的n天
     * @param time  时间格式：yyyy-MM-dd HH:mm:ss
     * @return  yyyy-MM-dd HH:mm:ss
     */
    public static String getBeforeNTime(String time,int n) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss).parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 - n);
 
        String afterTime = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss).format(c.getTime());
        return afterTime;
    }
    
    /**
     * 获取当前时间后的n天
     * @param time  时间格式：yyyy-MM-dd HH:mm:ss
     * @return  yyyy-MM-dd HH:mm:ss
     */
    public static String getAfterNTime(String time,int n) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss).parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 + n);
 
        String afterTime = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss).format(c.getTime());
        return afterTime;
    }
    
    /**
     * 获取当前时间前的n天
     * @param time  时间格式：yyyy-MM-dd
     * @return  yyyy-MM-dd
     */
    public static String getBeforeNDays(String dayStr,int n) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat(yyyy_MM_dd).parse(dayStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 - n);
 
        String afterTime = new SimpleDateFormat(yyyy_MM_dd).format(c.getTime());
        return afterTime;
    }
    
    /**
     * 获取当前时间后的n天
     * @param time  时间格式：yyyy-MM-dd
     * @return  yyyy-MM-dd
     */
    public static String getAfterNDays(String dayStr,int n) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat(yyyy_MM_dd).parse(dayStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 + n);
 
        String afterTime = new SimpleDateFormat(yyyy_MM_dd).format(c.getTime());
        return afterTime;
    }
    
    /**
	 * 获取当前时间后n分钟
	 * @param date_str  时间戳
	 * @param minutes 要增加的分钟数
	 * @return string
	 */
	public static String getAfterMinutes(Long date_str, int minutes) {
		date_str += minutes * 1000 * 60;// 在当前系统时间的基础上往后加minutes分钟
		SimpleDateFormat sFormat = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss);
		String time = sFormat.format(date_str);
		return time;
	}
	
	/**
	 * 获取前n个月
	 * @param dayStr yyyy_MM
	 * @param n
	 * @return
	 */
	public static String getBeforeNMonth(String dayStr,int n) {
		SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM);
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(new SimpleDateFormat(yyyy_MM).parse(dayStr));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.add(Calendar.MONTH, -n);
		Date m = c.getTime();
		return sdf.format(m);
	}
	
	/**
	 * 获取后n个月
	 * @param dayStr yyyy_MM
	 * @param n
	 * @return
	 */
	public static String getAfterNMonth(String dayStr,int n) {
		SimpleDateFormat sdf = new SimpleDateFormat(yyyy_MM);
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(new SimpleDateFormat(yyyy_MM).parse(dayStr));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.add(Calendar.MONTH, n);
		Date m = c.getTime();
		return sdf.format(m);
	}
	
	/**
	 * 获取前n个月
	 * @param dayStr
	 * @param n
	 * @param dateFormat 时间格式
	 * @return
	 */
	public static String getBeforeNMonth(String dayStr,int n,String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(new SimpleDateFormat(dateFormat).parse(dayStr));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.add(Calendar.MONTH, -n);
		Date m = c.getTime();
		return sdf.format(m);
	}
	
	/**
	 * 获取后n个月
	 * @param dayStr
	 * @param n
	 * @param dateFormat 时间格式
	 * @return
	 */
	public static String getAfterNMonth(String dayStr,int n,String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(new SimpleDateFormat(dateFormat).parse(dayStr));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.add(Calendar.MONTH, n);
		Date m = c.getTime();
		return sdf.format(m);
	}
	
	/**
	 * 获取当前日期是一年中第几周
	 * @param dayStr yyyy_MM_dd
	 * @return
	 */
	public static int getWeek(String dayStr) {
		SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd);
		Date date = null;
		try {
			date = format.parse(dayStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY); //设置星期一为一周第一天
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 获取本周开始日期（第一天是周一）
	 * @return 
	 */
	public static Date getBeginDayOfWeek() {
		Date date = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
			dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);

		return cal.getTime();
	}

	/**
	 * 获取本周结束日期（第一天是周一）
	 * @return 
	 */
	public static Date getEndDayOfWeek() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return weekEndSta;
	}

	/**
	 * 根据日期获取一周开始时间（第一天是周一）
	 * @param time yyyy_MM_dd
	 * @return 
	 */
	public static Date getBeginDayOfWeek(String time) {
		SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd);
		Date date = null;
		try {
			date = format.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
			dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);

		return cal.getTime();
	}

	/**
	 * 根据日期获取一周结束日期（第一天是周一）
	 * @param time yyyy_MM_dd
	 * @return 
	 */
	public static Date getEndDayOfWeek(String time) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek(time));
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return weekEndSta;
	}

    public static void main(String[] args) {
    	System.out.println(dateDiff("2018-03-24", "2018-03-25", "yyyy-MM-dd", "d"));
	}
	
	
}
